<style >
.ability {
  width: 260px;
  margin-right: 20px;
  float: right;
}
.abilityScorll {
  overflow-y: auto;
  max-height: 600px;
}
.shActive {
  color: #409eff !important;
  border-color: #c6e2ff !important;
  background-color: #ecf5ff !important;
}
.el-form-item {
  margin-bottom: 0;
}
.canvas1 {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  z-index: 15;
}
.sh-input {
  color: #409eff;
}
.sh-out {
  color: aqua;
}
canvas {
  border: 1px dashed black;
}
</style>
<template>
  <div class="demo-content">
    <section class="demo-text">
      <el-row>
        <el-col :span="5">
          <el-tabs v-model="activeName" :stretch="true">
            <el-tab-pane label="设备图元" name="devicelist" class="abilityScorll">
              <el-row>
                <el-col
                  :span="5"
                  :offset="1"
                  v-for="(key,value) in devicelist"
                  :key="value"
                  style="height:150px; position: relative;"
                >
                  <el-card
                    :body-style="{ padding: '0px' ,'text-align':'center',height:'60px', background: '#f7f7f7',
    border: '1px solid #1661b9',
    'line-height': '60px','object-fit':'contain' }"
                  >
                    <img
                      style="object-fit: contain;
    width: 100%;
    height: 100%;
    padding: 2px;
    box-sizing: border-box;"
                      :src="key.src"
                      alt
                      draggable="true"
                      @dragstart="deviceDragStart($event,value)"
                      :name="value"
                    />
                  </el-card>
                  <div
                    style="position: absolute;
                            bottom: 30px;text-align:center; font-size:12px;width: 100%;"
                  >
                    <span>{{value}}</span>
                  </div>
                </el-col>
              </el-row>

              <!-- <img
                :src="url"
                alt
                draggable="true"
                ondragstart="event.dataTransfer.setData('name','柱上式断路器（通）')"
                name="柱上式断路器（通）"
              >
              <span>柱上式断路器（通）</span>-->
            </el-tab-pane>
            <el-tab-pane label="画笔工具" name="brush">
              <el-card :body-style="{ padding: '0px' }">
                <div style="padding: 14px;">
                  <el-button-group>
                    <el-button @click="drawstart" :class="editable?'shActive':''">开始编辑</el-button>
                    <el-button @click="drawend" :class="editable?'':'shActive'">结束编辑</el-button>
                  </el-button-group>
                  <el-button-group>
                    <el-button @click="undo">撤销</el-button>
                    <el-button @click="back">重做</el-button>
                    <el-button @click="del">删除</el-button>
                  </el-button-group>
                  <el-button-group>
                    <el-button
                      v-for="item,index in drawtypelist"
                      :type="item.type"
                      @click="draw(item.type)"
                      :class="drawtype==item.type?'shActive':''"
                      :key="item.type"
                    >{{item.name}}</el-button>
                  </el-button-group>
                </div>
                <div style="padding:14px">
                  <el-form ref="form" :model="colorList" label-width="80px">
                    <el-form-item label="边框">
                      <el-color-picker v-model="colorList.stroke" @change="changestroke"></el-color-picker>
                    </el-form-item>
                    <el-form-item label="填充">
                      <el-color-picker v-model="colorList.fill" @change="changefill"></el-color-picker>
                    </el-form-item>
                  </el-form>
                </div>
              </el-card>
            </el-tab-pane>
            <el-tab-pane label="样式" name="style" class="abilityScorll">
              <el-button>保存</el-button>
              <cstyle
                v-for="item in stylelist"
                :target="activeobj"
                :name="item.name"
                :keyword="item.key"
                :type="item.type"
                :setting="item.setting"
                :Informatter="item.Informatter"
                :Outformatter="item.Outformatter"
                :key="'s'+item.key"
              ></cstyle>
            </el-tab-pane>
            <el-tab-pane label="设备属性" name="attr" class="abilityScorll">
              <el-form ref="attForm" :model="attForm">
                <el-form-item v-for="item,key in attForm.attribute" :key="item.name">
                  <el-checkbox :label="item.name+'('+key+')'" name="type" v-model="item.checked"></el-checkbox>
                  <el-input placeholder="请输入内容" v-model="item.value" size="medium" class="ability"></el-input>
                </el-form-item>
              </el-form>
            </el-tab-pane>
                        <el-tab-pane label="编辑事件" name="eventslist" class="abilityScorll">

            </el-tab-pane>
          </el-tabs>
        </el-col>
        <el-col :span="12">
          <h1>属性设计</h1>
          <el-button-group>
            <el-button @click="drag">手型拖拽</el-button>
            <el-button @click="group">组合</el-button>
            <el-button @click="toActiveSelection">解除组合</el-button>
            <el-button @click="Copy">复制</el-button>
            <el-button @click="Paste">粘贴</el-button>
            <el-button @click="clear">清除复制</el-button>
            <el-button @click="reload">刷新</el-button>
            <el-button @click="zoomToPoint">放缩</el-button>
          </el-button-group>
          <el-button-group>
            <el-button @click="drawstart" :class="editable?'shActive':''">开始编辑</el-button>
            <el-button @click="drawend" :class="editable?'':'shActive'">结束编辑</el-button>
          </el-button-group>
          <el-button-group>
            <el-button @click="undo">撤销</el-button>
            <el-button @click="back">重做</el-button>
            <el-button @click="del">删除</el-button>
            <el-button @click="delEdit">清空编辑</el-button>
            <el-button @click="saveEdit">保存</el-button>
            <el-button @click="downloadfile">保存文件</el-button>
            <el-button @click="addhotspot">添加热点</el-button>
            <el-button @click="clearhotspot">清除热点</el-button>
          </el-button-group>
          <div style="position:relative;margin:30px" ref="canvasparents">
            <canvas id="canvas" width="600" height="600" ref="canvas"></canvas>
            <!-- <canvas id="canvas1" width="1200" height="600" class="canvas1"></canvas> -->
          </div>
        </el-col>
        <el-col :span="6">
          <el-tabs v-model="activeObjlist" :stretch="true">
            <el-tab-pane label="元素列表" name="objlist" class="abilityScorll" v-if="refresh">
              <tree
                :data="objlist"
                :activelist="ActiveTreeList"
                :setting="defaultProps"
                @ItemCheck="activeSection"
              ></tree>
            </el-tab-pane>
            <el-tab-pane label="JSON数据" name="json" class="abilityScorll">
              <div style="height:100%">
                <json-viewer :value="objTojson||{}" :expand-depth="5" copyables></json-viewer>
              </div>
            </el-tab-pane>
            <!-- <el-tab-pane label="事件" name="events" class="abilityScorll">

            </el-tab-pane>-->
            <!-- <el-tab-pane label="cmd" name="cmd" class="abilityScorll">
              <el-input
                type="text"
                prefix="输入指令"
                :rows="5"
                :autosize="true"
                v-model="cmdinput"
                @keyup.enter.native="handeexclue"
              >
                <el-button slot="append" @click="handeexclue">执行</el-button>
              </el-input>
              <div v-for="cmd in cmdlist" :class="'sh-'+cmd.type">
                <div>
                  <span>{{cmd.time | format('HH:mm:ss')}} ：</span>
                  <json-viewer
                    v-if="typeof cmd.value == 'object'"
                    :value="cmd.value"
                    :expand-depth="5"
                  ></json-viewer>
                  <span v-else>{{cmd.value}}</span>
                </div>
              </div>
            </el-tab-pane>-->
          </el-tabs>
        </el-col>
      </el-row>

      <p
        style="text-align:right;padding-right:60px;    position: absolute;
    right: 0;
    bottom: 0;
    z-index: 9999;
    pointer-events: none;"
      >@王睿杰 2019.1.23</p>
    </section>
  </div>
</template>
<script>
/**
 * write a component's description
 * 包含了绘制插件和工具栏，等等的编辑器组件
 */
import BaseCanvas from "@/js/staticCanvas.js";
import base from "@/js/companyBase.js";
import rluer from "@/js/rluer.js";
import history from "@/js/sc_history.js";
import interactive from "@/js/fabric.interactive.js";
import Cstyle from "./cstyle";
import {
  stylelist,
  events,
  drawtypelist,
  exportlist,
  CanvasStaticBase
} from "./setting";
import tree from "./tree";
import { devicelist, deviceloader, createdevice } from "@/js/deviceloader";
import alldevice from "@/js/Alldevice.js";
import { exportJson, SaveFile, append, decoration } from "@/js/bToa";
function evaltest(string) {
  try {
    return eval(string);
  } catch (e) {
    return e.message;
  }
}
export default {
  components: {
    Cstyle,
    tree
  },
  /**
   * @description 返回的数据
   * @returns {Object}
   */
  data() {
    return {
      drawtypelist, //绘制类型列表
      activeObjlist: "json", //右侧tab切换
      editable: false, //是否编辑状态
      canvas: null, //画布
      _clipboard: null, //粘贴板
      mouseevent: null, //复制粘贴实践
      refresh: true, //刷新控制
      devicelist,
      colorList: {
        //颜色控制器列表
        fill: "#ff0000",
        stroke: "#002546",
        strokeWidth: 1
      }, //树状结果默认显示
      defaultProps: {
        name: "name",
        children: "_objects"
      },
      events, //监听的事件
      activeName: "devicelist", //左侧列表
      _history: null, //历史
      _start: null, //绘制开始坐标（已弃用）
      isDrawingMode: true, //是否在绘制模式（已弃用）
      _drawingobj: null, //当前正在绘制的元素对象（已弃用）
      attForm: {
        attribute: base,
        style: {}
      },
      interactive: null, //交互器
      activeobj: null, //当前活跃的元素
      in1: null, //绘制器的交互区
      stylelist, //样式列表
      cmdlist: [],
      cmdinput: "",
      canvasbase: null,
      CanvasStaticBase,
      editDevice: null
    };
  },
  methods: {
    saveEdit() {
      const _this = this;
      if (this.editDevice) {
        this.canvas._objects.shift();
        let data = exportJson(this.canvas, exportlist);
        data = append(this.attForm.attribute, data);
        data.name = this.editDevice;
        createdevice(data);
        this.canvas._objects.unshift(this.canvasbase);
        this.canvas.renderAll();
        this.$forceUpdate();
      }
    },
    delEdit() {
      this.canvas.clear();
      this.canvas.add(this.canvasbase);
      this.editDevice = null;
    },
    drag() {
      this.canvas.draweditable(false);
    },
    zoomToPoint() {
      this.canvas.zoomToPoint({ x: 0, y: 0 }, 4.5);
      this.canvas.fire("ruler", {});
    },
    /**
     * @description 选中绘制元素，添加为热点，删除热点
     */
    addhotspot() {
      this.activeobj &&
        this.activeobj.set("hotspot", true) &&
        this.activeobj.set("opacity", "0.3");
      this.canvas.renderAll();
      this.activeobj &&
        this.$notify({
          title: "提示",
          message: "添加热点成功",
          duration: 2000,
          position: "top-left"
        });
    },
    clearhotspot() {
      this.activeobj &&
        this.activeobj.set("hotspot", false) &&
        this.activeobj.set("opacity", "1");
      this.canvas.renderAll();
      this.activeobj &&
        this.$notify({
          title: "提示",
          message: "清除热点成功",
          duration: 2000,
          position: "top-left"
        });
    },
    /**
     * @description 将图形元素下载为js文件
     */
    downloadfile() {
      let name = this.attForm.attribute.name.value || "test";
        this.canvas._objects.shift();
      let data = exportJson(this.canvas, exportlist);
      data = append(this.attForm.attribute, data);
      data.name = name;
      data = decoration(JSON.stringify(data, null, "\t"), name);
      this.canvas._objects.unshift(this.canvasbase);
      SaveFile(new Blob([data]), name + ".js");
    },
    /**
     * @description 添加或删除动作
     * @param {any} item
     * TODO 为图元添加动作，未使用
     */
    addOrRemove(item) {
      if (this.activeobj) {
        this.activeobj.set(item.type, item.event);
        if (!this.activeobj.actionCommad) {
          this.activeobj.set("actionCommad", {});
        }
        this.activeobj.actionCommad[item.type] = [];
      }
    },
    /**
     * 命令行调用输出
     */
    /**
     * @description
     * @param {String} input
     * @returns {any}
     */
    cmdoutput(input) {
      let d = evaltest.call(this.activeobj, input);
      d === undefined ? (d = "undefined") : d;
      d === null ? (d = "null") : d;
      d.toJSON ? (d = d.toJSON()) : d;
      this.cmdlist.push({
        type: "out",
        time: new Date(),
        value: d
      });
      this.canvas.renderAll();
      return (this.cmdinput = "");
    },
    /**
     * 命令行输入
     */
    /**
     * @description
     * @returns {any}
     */
    handeexclue() {
      if (this.cmdinput === "clear") {
        this.cmdlist.splice(0);
        this.cmdinput = "";
        return false;
      }
      this.cmdlist.push({
        type: "input",
        time: new Date(),
        value: this.cmdinput
      });
      return this.cmdoutput(this.cmdinput);
    },
    /**
     * 激活选中
     */
    /**
     * @description
     * @param {any} item
     * @param {any} index
     */
    activeSection(item, index) {
      this.canvas.setActiveObject(item);
      this.canvas.renderAll();
    },
    /**
     * 解除组合
     */
    /**
     * @description
     * @returns {any}
     */
    toActiveSelection() {
      let _this = this;
      if (_this.canvas.getActiveObject() == null) {
        return false;
      }
      // console.log(_this.canvas.getActiveObject().toActiveSelection())
      _this.canvas.getActiveObject() &&
      _this.canvas.getActiveObject().type == "group"
        ? _this.canvas.getActiveObject().toActiveSelection()
        : _this.$notify({
            title: "提示",
            message:
              _this.canvas.getActiveObject().type + "是无法拆分组合的元素类型",
            duration: 2000,
            position: "top-left"
          });
    },
    /**
     * 生成组合
     */
    /**
     * @description
     * @returns {any}
     */
    group() {
      let _this = this;
      if (_this.canvas.getActiveObject() == null) {
        return false;
      }
      _this.canvas.getActiveObject() &&
      _this.canvas.getActiveObject().type == "activeSelection"
        ? _this.canvas.getActiveObject().toGroup()
        : _this.$notify({
            title: "提示",
            message:
              _this.canvas.getActiveObject().type + "是无法组合的元素类型",
            duration: 2000,
            position: "top-left"
          });
    },
    deviceDragStart($event, value) {
      $event = event || window.event;
      $event.dataTransfer.setData("name", value);
    },
    /**
     * 修改边框颜色响应
     */
    /**
     * @description
     * @param {any} value
     */
    changestroke(value) {
      this.in1.setStyle("stroke", value);
    },
    /**
     * 修改填充颜色响应
     */
    /**
     * @description
     * @param {any} value
     */
    changefill(value) {
      this.in1.setStyle("fill", value);
    },
    /**
     * 修改边框宽度
     */
    /**
     * @description
     * @param {any} value
     */
    changesstrokeWidth(value) {
      this.in1.setStyle("strokeWidth", value);
    },
    /**
     * 撤销
     */
    /**
     * @description
     */
    undo() {
      this._history.undo();
    },
    /**
     * 回退、重做
     */
    /**
     * @description
     */
    back() {
      this._history.do();
    },
    /**
     * 删除
     */
    /**
     * @description
     */
    del() {
      let obj = this.canvas.getActiveObject();
      if (!obj) {
        return;
      }
      let _this = this;
      if (obj && obj._objects) {
        obj._objects.forEach(element => {
          _this.canvas.remove(element);
          this.canvas.fire("remove", { target: element });
        });
      } else {
        this.canvas.remove(obj);
        this.canvas.fire("remove", { target: obj });
      }
    },
    /**
     * 绘制，选择绘制类型
     */
    /**
     * @description
     * @param {any} type
     */
    draw(type) {
      this.canvas.chooseDrawtype(type);
    },
    /**
     * 开始编辑
     */
    /**
     * @description
     */
    drawstart() {
      this.isDrawingMode = true;
      this.canvas.draweditable(true);
      this.editable = true;
    },
    /**
     * 结束编辑
     */
    /**
     * @description
     */
    drawend() {
      this.isDrawingMode = false;
      this.canvas.draweditable(false);
      this.editable = false;
    },
    /**
     * 刷新dom
     */
    /**
     * @description
     */
    reload: function() {
      this.refresh = false;
      this.refresh = true;
    },
    /**
     * @description
     */
    clear() {
      this._clipboard = null;
      this.mouseevent = null;
    },
    addbackgroundRound() {
      this.canvasbase = new fabric.Rect(this.CanvasStaticBase);
      return this.canvasbase;
    },
    /**
     * @description
     */
    Copy() {
      // clone what are you copying since you
      // may want copy and paste on different moment.
      // and you do not want the changes happened
      // later to reflect on the copy.
      let _this = this;
      _this.mouseevent = null;
      this.canvas.getActiveObject() &&
        this.canvas.getActiveObject().clone(function(cloned) {
          _this._clipboard = cloned;
          _this.$notify({
            title: "提示",
            message: "复制成功",
            duration: 2000,
            position: "top-left"
          });
        });
    },
    Paste(e) {
      let _this = this;
      let canvas = _this.canvas;
      let _clipboard = _this._clipboard;
      if (!_this._clipboard) {
        _this.$notify({
          title: "提示",
          message: "需要先进行复制才能粘贴",
          duration: 2000,
          position: "top-left"
        });
        return;
      }
      let pointer = e.pointer || {};
      // clone again, so you can do multiple copies.
      _this._clipboard.clone(function(clonedObj) {
        canvas.discardActiveObject();
        clonedObj.set({
          left: pointer.x || clonedObj.left + 10,
          top: pointer.y || clonedObj.top + 10,
          evented: true
        });
        if (clonedObj.type === "activeSelection") {
          // active selection needs a reference to the canvas.
          clonedObj.canvas = canvas;
          clonedObj.forEachObject(function(obj) {
            canvas.add(obj);
          });
          // this should solve the unselectability
          clonedObj.setCoords();
        } else {
          canvas.add(clonedObj);
        }
        // _clipboard.top += 10;
        // _clipboard.left += 10;
        canvas.setActiveObject(clonedObj);
        canvas.requestRenderAll();
      });
    }
  },
  computed: {
    ActiveTreeList() {
      if (this.activeobj && this.activeobj.type == "activeSelection") {
        return this.activeobj._objects.map(ele => ele.did);
      } else {
        return (
          (this.canvas && this.canvas.getActiveObjects().map(ele => ele.did)) ||
          []
        );
      }
    },
    /**
     * 返回绘制类型
     */
    /**
     * @description
     * @returns {any}
     */
    drawtype() {
      if (this.canvas) {
        return this.canvas.getdrawtype();
      } else {
        return "";
      }
    },
    /**
     * 返回元素列表
     */
    /**
     * @description
     * @returns {any}
     */
    objlist() {
      return this.canvas && this.canvas._objects;
    },
    /**
     * @description
     * @returns {any}
     */
    objTojson() {
      return this.canvas && this.canvas.toDatalessJSON(exportlist, true);
    }
  },
  watch: {
    /**
     * @description
     * @param {any} newval
     * @param {any} oldval
     */
    objlist(newval, oldval) {
      this.reload();
    },
    /**
     * @description
     * @param {any} newval
     */
    activeobj(newval) {
      if (newval) {
        this.activeName = "style";
        this.activeObjlist = "objlist";
      } else {
        this.activeName = "devicelist";
        this.activeObjlist = "json";
      }
    }
  },
  /**
   * 实例挂载后执行的事件
   */
  mounted() {
    let that = this;
    /**
     * 1.生成画布
     * 2.将交互器赋值给data，以便后续操作
     * 3.设置绘制类型为矩形
     * 4.设置监听事件，监听元素改变
     */
    this.$nextTick(() => {
      let canvas;

      canvas = this.canvas = new BaseCanvas("canvas");
      window.canvas1 = canvas;
      canvas.init();
      let test = new fabric.CircleBrush(canvas);
      console.log(test)
      canvas.addRluer();
      canvas.draweditable(false);
      this._history = canvas.getHistory();
      this.interactive = canvas.getInteractor();
      this.in1 = canvas.getMaskInteractor();
      this.events.map(item => {
        canvas.on(item, function(e) {
          that.activeobj = null;
          that.activeobj = e.target || canvas.getActiveObject();
        });
      });
      canvas.on("mouse:move", function(e) {
        that.mouseevent = e;
      });
      // canvas.add(this.addbackgroundRound());
      this.zoomToPoint();
      //fabric自己封装了event事件，后面可以不需要记录，使用内置方法Canvas.getPointer
      //   canvas.on("mouse:down", function(e) {
      //     console.log(12);
      //   });
      //   canvas.off("mouse:down", abc);
      this.$refs.canvasparents.addEventListener("dragover", event => {
        event.preventDefault();
        return;
      });
      function addDeviceForEdit(name){
                that.editDevice = name;
        let device = getcolone(devicelist, name, exportlist);
        device.set({
          top: 50,
          left: 50,
          label: name
          // lockScalingX: true,
          // lockScalingY: true
        });
        for (let item in device.attr) {
          // console.log(device.attr)
          device.attr[item].checked = true;
        }
        that.attForm.attribute = Object.assign(
          that.attForm.attribute,
          device.attr
        );
        canvas.clear();
        // canvas.add(that.canvasbase);
        canvas.add(device);
        device.setCoords();
        device.toActiveSelection();
        that.activeobj = null;
        that.activeobj = canvas.getActiveObject();

      }
      this.$refs.canvasparents.addEventListener("drop", event => {
        event.preventDefault();
        let name = event.dataTransfer.getData("name");
          addDeviceForEdit(name)
      });
      window.addEventListener("keydown", function(e) {
        if (e && e.ctrlKey) {
          if (e.keyCode == 67) {
            that._clipboard = that.canvas.getActiveObject();
          }
          if (e.keyCode == 86) {
            that.Paste(that.mouseevent);
          }
        }
      });
      if(this.$route.query.device){
        addDeviceForEdit(this.$route.query.device)
      }
    });
    function getcolone(devicelist, name, exportlist) {
      let device;
      devicelist[name].clone(function(cloned) {
        device = cloned;
      }, exportlist);
      return device;
    }
    deviceloader(alldevice);
  },
  /**
   * @description
   */
  distoryed() {
    window.removeEventListener("keydown");
  }
};
</script>

